<?php

declare(strict_types=1);

namespace app\common\controller;

use app\common\service\third_party_api\WechatApiService;
use think\App;
use think\exception\ValidateException;
use think\response\Json;

/**
 * 微信回调控制器
 * 负责接收微信的各种回调通知，包括获取用户信息、处理授权回调等
 */
class WechatCallback
{
    /**
     * 微信API服务实例
     * @var WechatApiService
     */
    protected $wechatApiService;

    /**
     * 应用实例
     * @var App
     */
    protected $app;

    /**
     * 构造函数
     * @param App $app 应用实例
     * @param WechatApiService $wechatApiService 微信API服务实例
     */
    public function __construct(App $app, WechatApiService $wechatApiService)
    {
        $this->app = $app;
        $this->wechatApiService = $wechatApiService;
    }

    /**
     * 获取微信用户信息
     * @param string $openid 用户的openid
     * @return Json
     */
    public function getUserInfo($openid)
    {
        try {
            // 参数验证
            if (empty($openid)) {
                throw new ValidateException('openid不能为空');
            }

            // 调用微信API服务获取用户信息
            $userInfo = $this->wechatApiService->getUserInfo($openid);

            // 根据获取结果返回对应的响应
            if ($userInfo) {
                return json([
                    'code' => 0,
                    'msg' => 'success',
                    'data' => $userInfo
                ]);
            } else {
                return json([
                    'code' => 1,
                    'msg' => '获取用户信息失败'
                ]);
            }
        } catch (ValidateException $e) {
            // 记录异常日志
            $this->app->log->error('获取微信用户信息参数验证失败: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            // 记录异常日志
            $this->app->log->error('获取微信用户信息异常: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => '系统异常'
            ]);
        }
    }

    /**
     * 微信授权回调处理
     * @return Json
     */
    public function oauthCallback()
    {
        try {
            // 获取回调参数
            $code = $this->app->request->get('code', '');
            $state = $this->app->request->get('state', '');

            // 参数验证
            if (empty($code)) {
                throw new ValidateException('授权code不能为空');
            }

            // 获取微信openid和access_token
            $oauthInfo = $this->wechatApiService->getOpenIdByCode($code);

            // 根据获取结果返回对应的响应
            if ($oauthInfo && isset($oauthInfo['openid'])) {
                // 如果需要获取用户详细信息，可以调用以下方法
                // $userInfo = $this->wechatApiService->getUserInfoBySnsAccessToken($oauthInfo['access_token'], $oauthInfo['openid']);
                // 可以在这里处理用户授权后的业务逻辑，如创建或更新用户信息等

                return json([
                    'code' => 0,
                    'msg' => 'success',
                    'data' => $oauthInfo
                ]);
            } else {
                return json([
                    'code' => 1,
                    'msg' => '获取授权信息失败'
                ]);
            }
        } catch (ValidateException $e) {
            // 记录异常日志
            $this->app->log->error('微信授权回调参数验证失败: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            // 记录异常日志
            $this->app->log->error('微信授权回调处理异常: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => '系统异常'
            ]);
        }
    }

    /**
     * 生成JS-SDK签名
     * @param string $url 当前页面URL
     * @return Json
     */
    public function getJsSdkSign($url)
    {
        try {
            // 参数验证
            if (empty($url)) {
                throw new ValidateException('URL不能为空');
            }

            // 调用微信API服务生成签名
            $signInfo = $this->wechatApiService->generateJsSdkSign($url);

            // 根据生成结果返回对应的响应
            if ($signInfo) {
                return json([
                    'code' => 0,
                    'msg' => 'success',
                    'data' => $signInfo
                ]);
            } else {
                return json([
                    'code' => 1,
                    'msg' => '生成签名失败'
                ]);
            }
        } catch (ValidateException $e) {
            // 记录异常日志
            $this->app->log->error('生成JS-SDK签名参数验证失败: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            // 记录异常日志
            $this->app->log->error('生成JS-SDK签名异常: ' . $e->getMessage());
            return json([
                'code' => 1,
                'msg' => '系统异常'
            ]);
        }
    }

    /**
     * 微信消息推送回调验证
     * @return string
     */
    public function messageNotify()
    {
        try {
            // 获取微信服务器发送的验证参数
            $signature = $this->app->request->get('signature', '');
            $timestamp = $this->app->request->get('timestamp', '');
            $nonce = $this->app->request->get('nonce', '');
            $echostr = $this->app->request->get('echostr', '');

            // 验证服务器地址
            if ($this->checkSignature($signature, $timestamp, $nonce)) {
                // 首次验证时返回echostr
                return $echostr;
            } else {
                // 处理微信消息推送
                $postData = file_get_contents('php://input');
                $this->app->log->info('接收到微信消息: ' . $postData);

                // 这里可以添加消息处理逻辑

                // 返回成功响应
                return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            }
        } catch (\Exception $e) {
            // 记录异常日志
            $this->app->log->error('微信消息回调处理异常: ' . $e->getMessage());
            return '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统异常]]></return_msg></xml>';
        }
    }

    /**
     * 验证微信服务器签名
     * @param string $signature 签名
     * @param string $timestamp 时间戳
     * @param string $nonce 随机数
     * @return bool 验证结果
     */
    private function checkSignature($signature, $timestamp, $nonce)
    {
        // 获取微信配置的token
        $token = config('wechat.token', '');
        if (empty($token)) {
            return false;
        }

        // 对token、timestamp和nonce按字典序排序
        $tmpArr = [$token, $timestamp, $nonce];
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        // 比较生成的签名和微信服务器发送的签名
        return $tmpStr === $signature;
    }
}
